RUST. Энтерпрайз Эдишин В предыдущей главе я возносил хвалы Rust, как новому бекенду для EXE/OM программирования. Что меня покорило -- это количество всяких функциональных подходов и трюков типа трансмутации (можете думать об этом как сиплюсплюсном касте) блоков памяти. На практике move семантику в Rust не используют, и везде где надо что-то распарсать -- вы данные никогда не копируете из буфера, а просто накадывает свои структуры на него. Если вы поищете по гитхабу и интернетах zero-copy вы в основом будете попадать на Rust проекты -- это своего рода булшит-баз-кейворд. В реальности же существует очень мало проектов продакшин уровня где внутри стоят преаллоцированные буфера или Vec. Так как проектов на Rust мало, я просмотрел за неделю их все и вот, что могу сказать по этому поводу. Tokio, группировка или амбрелла сетевого стека и канального уровня для проектов основаных на ленивых стримах. Настоящие функциональные стримы со своей палитрой комбинаторов и их oneshot версиями -- футурами. Основано на библиотеке future-rs. Я лично не вижу глубокого смысла разделять на Future и Streams. mio. Tokio основан на mio -- библиотеке которую сейчас в мире Rust форсят в качестве де-факто стандарта который скрывает Windows/Linux/Mac сетевые флейворы. Из-за этого при втаскивании mio вы тянете 10 зависимостей. Код внутри mio ад и погибель, но никто туда не смотри и все пульзуются с радостью прописывая у себя единственную зависимость от mio. Казалось бы все круто есть функциональные стримы и на них же построенный ввод-вывод, но нет этого недостаточно, надо же еще протоколы, состояния, сессии, в функциональном мире на каждую штуку такую вы должны иметь свои стримы свои комбинаторы и на джава-подобном Rust языке все это выглядит не очень. Ну как scalaz только развернутый до java. Там кстати счас есть польностью аналогичные функциональные стеки на Java. Вот хасид недавно выкатывал монады и другие штука на octarine и еще есть похожая тема на Java 8 -- derive4j. Так вот Rust -- это приблизительно тоже самое, только больше байтойобства -- можно мапить прямо на таблицу виртуальных методов как Vec, и по ней бегать курсорами. Ну и gc нет, что тоже как бы хорошо. Вообщем такая простая задача как заспавнить долгоикрающий переподнимающийся клиентский коннекшин к базе данных например -- является на токио почти неподъемное задачей. Для этого под амбреллой Токио пацаны еще сделали несколько отдельных библиотек типа tokio-proto, tokio-service и написали на них не то что бы фонтанирующий единорогами tokio-redis клиент. Пример Токио нам как бы показывает, что функциональных программистов пока не надо допускать к проектированию сетевых трактов :-) Поэтому я начал копать глубже. LMAX. В терминологии Rust и его интерфейсах Queue существуют абстрактные очереди SPSC, MPSC, SPMC, которые могут бекендиться разными типами данных, как то Vec, &mut T или менее желанными Box типами. Самые быстрые очереди типа точка точка на Vec и трансмутации имеют кросс-тред латенси 10-40нс. LMAX Disruptor паттер SPMC имеет свою имлементацию на Rust, которая называется Turbine, по сути это внутри Vec, с множественными курсорами, данные внутри не копируются, а передвигаются только курсоры пайпов. Интересная штука, но как-то все задрочено на этом меше который строится, хочется больший контроль и композабелность, и если нада move семантика. nanomsg. Третий проект достоин внимания инженеров -- это имплементация nanomsg протокола, который на самом деле является группой протоколов на абстрактных пайпах: PROTOCOL | SEND | RECV ------------------------------------------- bus | broadcast | fairqueue pair | single | single publisher | broadcast | XXX pull | XXX | fairqueue push | loadbalancer | XXX reply | target | fairqueue request | loadbalancer | target respondent | target | fairqueue subscribe | XXX | fairqueue survey | broadcast | fairqueue Мне удалось урезать ядро сетевого стека до 1200 LOC. Session Types. Старые добрые сессионные типы на Rust. Тут имеются ввиду сессионные типы Кохея Хонды, который второй после Милнера по Пи-калкулусу: http://mrg.doc.ic.ac.uk/kohei/ По сути Rust версия http://munksgaard.me/laumann-munksgaard-larsen.pdf является портом Haskell версии http://users.eecs.northwestern.edu/~jesse/pubs/haskell-session-types/session08.p df Да да, любая библиотека на Haskell транслируется в Rust :-) Кратко что такое сессионные типы. Сессионные тип -- это большой вложеный каррированый индуктивный тип (enum), который включает в себя все сообщения протокола и их ветвтления, а также рекурсию протокола, которая структурируется, т.е. ограничивается нумералами черча построенными на фантомных типах, которые удаляются после стадии компиляции. Можно генерировать референсные имплементации протоколов по их типам, эти типы полностью специфицирует канал точка-точка, изменение протокола стриктит тайпчекинг клиента и сервера. Парсер на кобинаторах nom. Я думаю, что это библиотеку тоже надо включить в обзор продакшин решений на Rust. Особо рассказывать нечего, полный набор комбинаторов, высокая портируемость подобных комбинаторных парсеров с других языков типа Haskell, Clojure, Scala и т.д. Можно прямо брать и юзать. Ебет аттопарсек на порядки. manual C 62,451 ns/iter (+/- 1000 ns) 300,000 ns/iter (+/- 16 ns) nom 48,420 ns/iter (+/- 2,662 ns) 250,547 ns/iter (+/- 6,967 ns) attoparsec 241.5 μs/iter (+/-5.7 μs) 1.836 ms/iter (+/- 137 μs) Всё остальное -- капрограммы и уриналы.